﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace Face_Recognition
{
    public static class TextureFilters
    {
        public static bool[,] TextureCheck(Bitmap bitmap,bool[,] colorMask, int size)
        {
            Texel t;

            bool[,] mask = colorMask;

            for (int w = 0; w < bitmap.Width - size; w += size)
            {
                for (int h = 0; h < bitmap.Height - size; h += size)
                {
                    if (colorMask[h, w])
                    {
                        t = new Texel(size, bitmap, new int[2] { w, h });

                        if (t.checkTexture() == false)
                        {
                            for (int i = 0; i < size; i++)
                            {
                                for (int j = 0; j < size; j++)
                                {
                                    mask[h + i, w + j] = false;
                                    bitmap.SetPixel(w, h, Color.Red);
                                }
                            }
                        }
                        //else
                        //{
                        //    for (int i = 0; i < size; i++)
                        //    {
                        //        for (int j = 0; j < size; j++)
                        //        {
                        //            mask[h + i, w + j] = true;
                        //        }
                        //    }
                        //}

                    }
                }
            }
            return mask;
        }

        public static Bitmap median(int scale, Bitmap bitmap)
        {
            int[,] matrixR = new int[scale, scale];
            int[,] matrixG = new int[scale, scale];
            int[,] matrixB = new int[scale, scale];

            for (int w = scale; w < bitmap.Width - scale; w++)
            {
                for (int h = scale; h < bitmap.Height - scale; h++)
                {
                    for (int i = -scale / 2; i < scale / 2; i++)
                    {
                        for (int j = -scale / 2; j < scale / 2; j++)
                        {
                            matrixR[i + scale / 2, j + scale / 2] = bitmap.GetPixel(w + i, h + j).R;
                        }
                    }

                    for (int i = -scale / 2; i < scale / 2; i++)
                    {
                        for (int j = -scale / 2; j < scale / 2; j++)
                        {
                            matrixG[i + scale / 2, j + scale / 2] = bitmap.GetPixel(w + i, h + j).G;
                        }
                    }

                    for (int i = -scale / 2; i < scale / 2; i++)
                    {
                        for (int j = -scale / 2; j < scale / 2; j++)
                        {
                            matrixB[i + scale / 2, j + scale / 2] = bitmap.GetPixel(w + i, h + j).B;
                        }
                    }

                    int r = 0, g = 0, b = 0;

                    for (int i = 0; i < scale; i++)
                    {
                        for (int j = 0; j < scale; j++)
                        {
                            r += matrixR[i, j];
                        }
                    }

                    r /= (matrixR.GetLength(0) * matrixR.GetLength(1));

                    for (int i = 0; i < scale; i++)
                    {
                        for (int j = 0; j < scale; j++)
                        {
                            g += matrixG[i, j];
                        }
                    }

                    g /= (matrixR.GetLength(0) * matrixR.GetLength(1));
                    for (int i = 0; i < scale; i++)
                    {
                        for (int j = 0; j < scale; j++)
                        {
                            b += matrixB[i, j];
                        }
                    }

                    b /= (matrixR.GetLength(0) * matrixR.GetLength(1));

                    Color color = Color.FromArgb(r, g, b);

                    bitmap.SetPixel(w, h, color);
                }
            }

            return bitmap;
        }

        public static bool[,] Sobel(Bitmap bitmap)
        {
            Bitmap tempBitmap = Morphology.DeepClone<Bitmap>(bitmap);

            short[,] xMatrix = new short[3, 3] { { -1, 0, 1 }, { -2, 0, 2 }, { -1, 0, 1 } };
            short[,] yMatrix = new short[3, 3] { { -1, -2, -1 }, { 0, 0, 0 }, { 1, 2, 1 } };
            short Xvalue = 0;
            short Yvalue = 0;
            short XYvalue = 0;
            short[,] grayscaleImage = new short[bitmap.Height, bitmap.Width];
            bool[,] mask = new bool[bitmap.Height, bitmap.Width];


            for (int w = 3; w < bitmap.Width - 3; w++)
            {
                for (int h = 3; h < bitmap.Height - 3; h++)
                {
                    grayscaleImage[h, w] = (short)(0.21 * tempBitmap.GetPixel(w, h).R + 0.71 * tempBitmap.GetPixel(w, h).G + 0.07 * tempBitmap.GetPixel(w, h).B);
                }
            }

            for (int w = 3; w < bitmap.Width - 3; w++)
            {
                for (int h = 3; h < bitmap.Height - 3; h++)
                {
                    Xvalue = 0;
                    Yvalue = 0;
                    XYvalue = 0;
                    for (int i = -1; i < 2; i++)
                    {
                        for (int j = -1; j < 2; j++)
                        {
                            Xvalue += (short)(grayscaleImage[h + i, w + j] * xMatrix[i + 1, j + 1]);
                            Yvalue += (short)(grayscaleImage[h + i, w + j] * yMatrix[i + 1, j + 1]);
                        }
                    }

                    XYvalue = (short)Math.Sqrt(Math.Pow(Xvalue, 2) + Math.Pow(Yvalue, 2));
                    if (/*(short)(XYvalue) > 0 && */ (short)(XYvalue) < 125)
                        mask[h, w] = false;
                    else
                    {
                        mask[h, w] = true;
                        bitmap.SetPixel(w, h, Color.BlueViolet);
                    }

                }
            }

            return mask;
        }

        public static bool[,] ColorSobel(Bitmap bitmap)
        {
            Bitmap tempBitmap = Morphology.DeepClone<Bitmap>(bitmap);

            short[,] xMatrix = new short[3, 3] { { -1, 0, 1 }, { -2, 0, 2 }, { -1, 0, 1 } };
            short[,] yMatrix = new short[3, 3] { { -1, -2, -1 }, { 0, 0, 0 }, { 1, 2, 1 } };

            short XRvalue = 0;
            short YRvalue = 0;
            short XYRvalue = 0;

            short XGvalue = 0;
            short YGvalue = 0;
            short XYGvalue = 0;

            short XBvalue = 0;
            short YBvalue = 0;
            short XYBvalue = 0;

            short XYvalue = 0;

            bool[,] mask = new bool[bitmap.Height, bitmap.Width];

            for (int w = 3; w < bitmap.Width - 3; w++)
            {
                for (int h = 3; h < bitmap.Height - 3; h++)
                {
                    XRvalue = 0;
                    YRvalue = 0;
                    XYRvalue = 0;

                    XGvalue = 0;
                    YGvalue = 0;
                    XYGvalue = 0;

                    XBvalue = 0;
                    YBvalue = 0;
                    XYBvalue = 0;

                    XYvalue = 0;
                    for (int i = -1; i < 2; i++)
                    {
                        for (int j = -1; j < 2; j++)
                        {
                            XRvalue += (short)(tempBitmap.GetPixel(w + j, h + i).R * xMatrix[i + 1, j + 1]);
                            YRvalue += (short)(tempBitmap.GetPixel(w + j, h + i).R * yMatrix[i + 1, j + 1]);

                            XGvalue += (short)(tempBitmap.GetPixel(w + j, h + i).G * xMatrix[i + 1, j + 1]);
                            YGvalue += (short)(tempBitmap.GetPixel(w + j, h + i).G * yMatrix[i + 1, j + 1]);

                            XBvalue += (short)(tempBitmap.GetPixel(w + j, h + i).B * xMatrix[i + 1, j + 1]);
                            YBvalue += (short)(tempBitmap.GetPixel(w + j, h + i).B * yMatrix[i + 1, j + 1]);
                        }
                    }

                    XYRvalue = (short)Math.Sqrt(Math.Pow(XRvalue, 2) + Math.Pow(YRvalue, 2));
                    XYGvalue = (short)Math.Sqrt(Math.Pow(XGvalue, 2) + Math.Pow(YGvalue, 2));
                    XYBvalue = (short)Math.Sqrt(Math.Pow(XBvalue, 2) + Math.Pow(YBvalue, 2));

                   // XYvalue = (short)Math.Sqrt(Math.Pow(XRvalue, 2) + Math.Pow(YRvalue, 2) + Math.Pow(XGvalue, 2) + Math.Pow(YGvalue, 2) + Math.Pow(XBvalue, 2) + Math.Pow(YBvalue, 2));

                    if ((short)XYRvalue < 100 && (short)XYGvalue < 100 && (short)XYBvalue < 100)
                        mask[h, w] = false;
                    else
                    {
                        mask[h, w] = true;
                        //bitmap.SetPixel(w, h, Color.BlueViolet);
                    }
                }
            }

            return Morphology.Thinning(mask);
        }

        public static Bitmap GaussianBlur(Bitmap bitmap)
        {
            Bitmap tempBitmap = Morphology.DeepClone<Bitmap>(bitmap);

            short[,] blurMatrix = new short[5, 5] { { 1, 4, 7, 4, 1 }, { 4,16,26,16,4 }, { 7,26,42,26,7 },{ 4,16,26,16,4 }, { 1, 4, 7, 4, 1 } };
            int r = 0;
            int g = 0;
            int b = 0;

            for (int w = 3; w < bitmap.Width - 3; w++)
            {
                for (int h = 3; h < bitmap.Height - 3; h++)
                {
                    r = 0;
                    g = 0;
                    b = 0;

                    for (int i = -2; i <= 2; i++)
                    {
                        for (int j = -2; j <= 2; j++)
                        {
                            r += (short)(bitmap.GetPixel(w+i, h+j).R * blurMatrix[i + 2, j + 2]);
                            g += (short)(bitmap.GetPixel(w+i, h+j).G * blurMatrix[i + 2, j + 2]);
                            b += (short)(bitmap.GetPixel(w+i, h+j).B * blurMatrix[i + 2, j + 2]);
                        }
                    }

                    r = (int)((float)r / 273.0);
                    g = (int)((float)g / 273.0);
                    b = (int)((float)b / 273.0);
                    bitmap.SetPixel(w, h, Color.FromArgb(r,g,b));
                }
            }

            return bitmap;
        }
    }
}
